#include "AssetModel.h"
#include "SelectorModel.h"
#include "ResultModel.h"
#include "ModelItems/ResponseItem.h"
#include "ModelItems/ResultItem.h"
#include "ModelItems/ResponseAttributeItem.h"
#include "ModelItems/AttributeItem.h"
#include "ModelItems/QuestionItem.h"

namespace Xps
{
	AssetModel::AssetModel(XpsAssets::AssetManager* am) : QStandardItemModel()
	{
		this->am = am;
		rootItem = invisibleRootItem();
		qm = new SelectorModel();
		attributesModel = new SelectorModel();

		// connect asset manager events to model
		connect(am, SIGNAL(sNewQuestion(int)), this, SLOT(addQuestion(int)));
		connect(am, SIGNAL(sNewResult(int)), this, SLOT(addResult(int)));
		connect(am, SIGNAL(sNewAttribute(int)), this, SLOT(addAttribute(int)));
		connect(am, SIGNAL(sNewResponseAttribute(int,int)), this, SLOT(addResponseAttribute(int,int)));
		connect(am, SIGNAL(sResponseAttributeRemoved(int,int)), this, SLOT(remResponseAttribute(int,int)));
		connect(am, SIGNAL(sQuestionRemoved(int)), this, SLOT(remQuestion(int)));
		connect(am, SIGNAL(sResultRemoved(int)), this, SLOT(remResult(int)));
		connect(am, SIGNAL(sAttributeRemoved(int)), this, SLOT(remAttribute(int)));
		connect(am, SIGNAL(sNewResponse(int,int)), this, SLOT(addResponse(int,int)));
		connect(am, SIGNAL(sResponseRemoved(int,int)), this, SLOT(remResponse(int,int)));
		
	}

	void AssetModel::addQuestion(int id)
	{
		TreeItem *item = new QuestionItem(am, id);
		questions.insert(id, item);
		questionsRootItem->appendRow(item);
	}

	void AssetModel::addResult(int id)
	{
		TreeItem *item = new ResultItem(am, id);
		results.insert(id, item);
		resultsRootItem->appendRow(item);
	}

	void AssetModel::addAttribute(int id)
	{
		TreeItem *item = new AttributeItem(am, id, ATTRIBUTE);
		attributes.insert(id, item);
		attributesRootItem->appendRow(item);
	}

	void AssetModel::addResponseAttribute(int rid, int aid)
	{
		TreeItem *item = new ResponseAttributeItem(am, aid, rid);
		responses[rid]->appendRow(item);
	}

	void AssetModel::remResponseAttribute(int rid, int aid)
	{
		TreeItem *item = responses[rid];

		int rowc = item->rowCount();

		for (int i = 0; i < rowc; i++)
		{
			TreeItem* ai = (TreeItem*) item->child(i);
			
			if (ai->getID() == aid)
			{
				item->takeRow(i);
				delete ai;
				return;
			}
		}
	}

	void AssetModel::addResponse(int qid, int rid)
	{
		TreeItem *item = new ResponseItem(am, rid, qid);
		responses.insert(rid, item);
		questions[qid]->appendRow(item);
	}

	void AssetModel::remQuestion(int id)
	{
		TreeItem *item = questions[id];
		QList<QStandardItem*> il = questionsRootItem->takeRow(item->row());
		while (item->hasChildren())
		{
			qDeleteAll(item->takeRow(0));
		}
		qDeleteAll(il);
	}

	void AssetModel::remResult(int id)
	{
		TreeItem *item = results[id];
		QList<QStandardItem*> il = resultsRootItem->takeRow(item->row());
		while (item->hasChildren())
		{
			qDeleteAll(item->takeRow(0));
		}
		qDeleteAll(il);
	}

	void AssetModel::remResponse(int qid, int rid)
	{
		TreeItem *item = questions[qid];

		int rowc = item->rowCount();

		for (int i = 0; i < rowc; i++)
		{
			TreeItem* ri = (TreeItem*) item->child(i);
			
			if (ri->getID() == rid)
			{
				item->takeRow(i);
				delete ri;
				return;
			}
		}
	}

	void AssetModel::remAttribute(int id)
	{
		// remove attributes from responses
		QList<int> remitems;

		for (int i = 0; i < responses.count(); i++)
		{
			TreeItem* r = responses.value(responses.keys().at(i));
			
			for (int j = 0; j < r->rowCount(); j++)
			{
				TreeItem* a = (TreeItem*) r->child(j);
				if(a->getID() == id)
					remitems.append(a->row());
			}
			
			while(remitems.count() > 0)
			{
				int pos = remitems.at(0);
				remitems.removeAt(0);
				r->removeRow(pos);
				
			}
		}

		// remove attribute from attributes branch
		TreeItem *item = attributes[id];

		QList<QStandardItem*> il = attributesRootItem->takeRow(item->row());
		while (item->hasChildren())
		{
			qDeleteAll(item->takeRow(0));
		}
		qDeleteAll(il);
	}

	void AssetModel::clear()
	{
		while(questionsRootItem->hasChildren())
		{
			qDeleteAll(questionsRootItem->takeRow(0));
		}

		while(attributesRootItem->hasChildren())
		{
			qDeleteAll(attributesRootItem->takeRow(0));
		}

		while(resultsRootItem->hasChildren())
		{
			qDeleteAll(resultsRootItem->takeRow(0));
		}
	}

	void AssetModel::init()
	{
		QSize size(10,35);
		QFont headfont("Arial", 10, QFont::Bold);

		questionsRootItem = new TreeItem(am, -1, QUESTIONS_ROOT);
		questionsRootItem->setText("Questions");
		questionsRootItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
		questionsRootItem->setFont(headfont);
		questionsRootItem->setSizeHint(size);
		questionsRootItem->setIcon(QIcon(":/rs/images/question.png"));
		rootItem->appendRow(questionsRootItem);

		attributesRootItem = new TreeItem(am, -1, ATTRIBUTES_ROOT);
		attributesRootItem->setText("Attributes");
		attributesRootItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
		attributesRootItem->setFont(headfont);
		attributesRootItem->setSizeHint(size);
		attributesRootItem->setIcon(QIcon(":/rs/images/attribute.png"));
		rootItem->appendRow(attributesRootItem);

		resultsRootItem = new TreeItem(am, -1, RESULTS_ROOT);
		resultsRootItem->setText("Results");
		resultsRootItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
		resultsRootItem->setFont(headfont);
		resultsRootItem->setSizeHint(size);
		resultsRootItem->setIcon(QIcon(":/rs/images/result.png"));
		rootItem->appendRow(resultsRootItem);

		attributesModel->setModel(this,1);
		qm->setModel(this,0);
	}
}